package com.lzl.netty.server;

import com.lzl.netty.server.handler.TimeServerHandler;
import com.lzl.netty.server.protobuf.MsgPro;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;

public class ServerMain {

    public static void runServer(Integer prot){
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG,1024)
                .childHandler(new ChanelInit());

        try {
            //绑定端口，同步等待成功
            ChannelFuture sync = bootstrap.bind(prot).sync();
            System.out.println("server started。。");

            /*
             * 这里会一直等待，直到socket被关闭
             * 等待服务端监听端口
             */
            sync.channel().closeFuture().sync();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }


    }

    private static class  ChanelInit extends ChannelInitializer<SocketChannel>{
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel.pipeline()
                    .addLast(new ProtobufVarint32FrameDecoder())//使用netty自带的解决半包的问题
                    .addLast(new ProtobufDecoder(MsgPro.UserMsg.getDefaultInstance()))//解码
                    .addLast(new ProtobufVarint32LengthFieldPrepender())//使用netty自带的工具，解决半包问题
                    .addLast(new ProtobufEncoder())//编码
                    .addLast(new TimeServerHandler());//执行的业务
        }
    }



    public static void main(String[] args) {
        runServer(8765);
    }



}
